想像你剛買了一台全新的家電,同時是一台智慧家居控制中心。這台裝置可以控制家裡的燈光、空調、音響,甚至幫你泡咖啡!不過當你打開說明書,發現需要安裝十幾個不同的應用程式來單獨操控每個裝置時,這一切變得繁瑣起來。於是你會開始想如果有一個簡單的按鈕讓你輕鬆掌控所有裝置那該多好!這就是門面模式 Facade Pattern 的可以發揮的地方。門面模式讓我們可以簡化複雜系統的使用介面,將多個操作包裝成一個簡單的介面,讓使用者感到舒適和便利。
門面模式是一種結構型設計模式,目的是為複雜系統提供一個簡單的介面,透過一個門面類別來隱藏系統的細節,讓使用者無需關心底層的運作方式。這個模式的核心思想就是隱藏系統的內部複雜度,對外提供一個簡單、統一的操作入口。
具體來說,門面模式並不改變系統內部的運作邏輯,而是提供一個統一的「門面」來簡化與系統的互動。使用者只需透過這個門面進行操作,而無需了解系統內部的多個模組是如何協同工作的。
視訊轉換是一個非常複雜的過程,牽涉到解碼、轉碼、編碼、壓縮等多個步驟。假設你正在開發一個應用程式,目標是將一段視訊從一種格式轉換成另一種格式。如果讓使用者手動操作每個步驟,這對非技術背景的使用者來說無疑是個大挑戰。而門面模式非常適合這樣的應用場景。
首先我們可以想像這個視訊轉換系統內部包含了多個模組,比如 Decoder
、Encoder
、Compressor
、AudioProcessor
、SubtitleHandler
和 ResolutionAdjuster
,它們負責不同的視訊處理任務。為了讓使用者不需要關心這些細節,我們可以建立一個門面 VideoConverterFacade
,讓這些模組協同工作。
內部模組可能是這樣的,
class Decoder {
public:
void decode(const std::string& file) {
std::cout << "Decoding " << file << std::endl;
}
};
class Encoder {
public:
void encode(const std::string& format) {
std::cout << "Encoding to " << format << std::endl;
}
};
class Compressor {
public:
void compress() {
std::cout << "Compressing video" << std::endl;
}
};
class AudioProcessor {
public:
void processAudio() {
std::cout << "Processing audio..." << std::endl;
}
};
class SubtitleHandler {
public:
void addSubtitle(const std::string& subtitleFile) {
std::cout << "Adding subtitle: " << subtitleFile << std::endl;
}
};
class ResolutionAdjuster {
public:
void adjustResolution(int width, int height) {
std::cout << "Adjusting resolution to " << width << "x" << height << std::endl;
}
};
接著我們來實現門面類別,讓它來協調這些模組的工作,並提供一個簡單的操作方法,
class VideoConverterFacade {
private:
Decoder decoder;
Encoder encoder;
Compressor compressor;
AudioProcessor audioProcessor;
SubtitleHandler subtitleHandler;
ResolutionAdjuster resolutionAdjuster;
public:
void convertVideo(const std::string& file, const std::string& format,
const std::string& subtitleFile, int width, int height) {
decoder.decode(file); // 解碼
audioProcessor.processAudio(); // 處理音訊
subtitleHandler.addSubtitle(subtitleFile); // 新增字幕
resolutionAdjuster.adjustResolution(width, height); // 調整解析度
compressor.compress(); // 壓縮影片
encoder.encode(format); // 編碼
}
};
現在我們可以在客戶端直接使用這個門面來進行視訊轉換,而無需了解內部的解碼、音訊、新增字幕、調整解析度、編碼和壓縮步驟,
int main() {
VideoConverterFacade converter;
converter.convertVideo("movie.mp4", "avi", "movie.srt", 1920, 1080);
return 0;
}
執行上述程式碼,我們會得到以下輸出:
Decoding movie.mp4
Processing audio...
Adding subtitle: movie.srt
Adjusting resolution to 1920x1080
Compressing video
Encoding to avi
在這個例子中,我們把多個步驟簡化成一個 convertVideo
方法,這讓使用者無需關心背後的具體操作,只需要指定原始檔案和目標格式即可完成任務。
門面模式的好處顯而易見,它簡化了使用者的操作體驗,讓他們不需要理解系統的複雜內部結構。這種方式提高了系統的可用性,尤其是當你有一個由多個子系統組成的複雜應用時,門面可以提供一個統一的入口,減少使用者的學習成本和操作壓力。
同時門面模式也提升了系統的模組化,因為每個子系統依然保持相對獨立。如果需要修改內部實現或新增新功能,只需要改動子系統,門面本身不必大幅修改,這增強了系統的可擴展性。
但門面模式也有缺點。當系統需求變得更加複雜時,門面的簡單操作可能無法滿足高階使用者的需求。他們可能希望能夠更深入地控制系統,這時門面反而可能會限制他們的靈活性。另外如果過度依賴門面來隱藏內部邏輯,可能會導致某些使用者忽視了系統真正的運作方式,導致未來難以進行細微的調整和除錯。
門面模式特別適合應用在那些需要隱藏系統複雜性的場景中。它透過提供一個簡單的介面,讓使用者能夠方便地與系統互動,無需深入了解內部細節。無論是在視訊轉換這樣的多步驟過程中,還是在其他複雜系統中,門面模式都能讓使用體驗更加友好且直觀。
使用門面模式時也要權衡簡化操作與系統靈活性之間的平衡,確保系統在簡單易用的同時,也能滿足高階使用者的進階需求。畢竟簡單不代表犧牲功能,這就是門面模式所帶來的設計智慧。
更多C++語言相關的文章,歡迎追蹤我的部落格。
https://shengyu7697.github.io/cpp-facade-pattern/